#region License

// This file is part of Grawlix.
// 
// Grawlix is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as
// published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
// Grawlix is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public
// License along with Grawlix.  If not, see
// <http://www.gnu.org/licenses/>.

#endregion

using System;
using System.Globalization;
using Grawlix.Geometry;

namespace Grawlix.Services.Rendering
{
	/// <summary>
	/// A single resolved character with position.
	/// </summary>
	public struct Glyph : IEquatable<Glyph>
	{
		/// <summary>
		/// The index of the glyph.
		/// </summary>
		private int _character;

		/// <summary>
		/// The position of the glyph.
		/// </summary>
		private Vector2 _position;

		/// <summary>
		/// Gets or sets the index of the glyph.
		/// </summary>
		/// <value>The index of the glyph within the font.</value>
		public int Character
		{
			get { return _character; }
			set { _character = value; }
		}

		/// <summary>
		/// Gets or sets the position of the glyph.
		/// </summary>
		/// <value>The position of the glyph on the screen.</value>
		public Vector2 Position
		{
			get { return _position; }
			set { _position = value; }
		}

		/// <summary>
		/// Indicates whether this instance and a specified object are
		/// equal.
		/// </summary>
		/// <param name="obj">Another object to compare to.</param>
		/// <returns>
		/// true if <paramref name="obj"/> and this instance are the
		/// same type and represent the same value; otherwise, false.
		/// </returns>
		public override bool Equals(object obj)
		{
			if (obj.GetType() != typeof(Glyph))
				return false;
			return Equals((Glyph)obj);
		}

		/// <summary>
		/// Indicates whether the current object is equal to another
		/// object of the same type.
		/// </summary>
		/// <param name="other">An object to compare with this object.
		/// </param>
		/// <returns>
		/// true if the current object is equal to the 
		/// <paramref name="other"/> parameter; otherwise, false.
		/// </returns>
		public bool Equals(Glyph other)
		{
			return other._position.Equals(_position) &&
			       other._character == _character;
		}

		/// <summary>
		/// Returns the hash code for this instance.
		/// </summary>
		/// <returns>
		/// A 32-bit signed integer that is the hash code for this
		/// instance.
		/// </returns>
		public override int GetHashCode()
		{
			unchecked
			{
				return (_position.GetHashCode() * 397) ^ _character;
			}
		}

		/// <summary>
		/// Returns a string representation of this object.
		/// </summary>
		/// <returns>
		/// A <see cref="T:System.String"/> containing information
		/// about the object.
		/// </returns>
		public override string ToString()
		{
			return string.Format(CultureInfo.InvariantCulture,
			                     "_position: {0}, _character: {1}",
			                     _position, _character);
		}

		/// <summary>
		/// Compares two <see cref="Glyph"/> structures for equality.
		/// </summary>
		/// <param name="left">The left-hand side of the comparison.
		/// </param>
		/// <param name="right">The right-hand side of the comparison.
		/// </param>
		/// <returns><c>true</c> if equal; else <c>false</c>.</returns>
		public static bool operator ==(Glyph left, Glyph right)
		{
			return left.Equals(right);
		}

		/// <summary>
		/// Compares two <see cref="Glyph"/> structures for inequality.
		/// </summary>
		/// <param name="left">The left-hand side of the comparison.
		/// </param>
		/// <param name="right">The right-hand side of the comparison.
		/// </param>
		/// <returns><c>false</c> if equal; else <c>true</c>.</returns>
		public static bool operator !=(Glyph left, Glyph right)
		{
			return !left.Equals(right);
		}
	}
}